﻿using System.Collections.Generic;

namespace CST_276_Lab_3
{
    public class DeskAssemblyLine : IObserver, IAssemblyLine
    {

        #region Members
        private readonly ISubject _automationController;
        private IProductionBehavior _productionBehavior;
        private DeskOrder _buildQue;
        #endregion

        #region Methods

        public DeskAssemblyLine(ISubject automationController)
        {
            this._automationController = automationController;
            this._automationController.RegisterObserver(this);
        }

        public Desk Update(ref Queue<DeskOrder> deskOrders)
        {
            // Grab desk off top of stack
            if (deskOrders.Count == 0) return null;
            lock (deskOrders)
            {
                if (deskOrders.Peek() != null)
                {
                    _buildQue = deskOrders.Dequeue();
                }
            }

            var desk = Build();
            return desk;
        }

        private void SetProductionBehavior(string type)
        {
            switch (type)
            {
                case "LeftL":
                    this._productionBehavior = new LeftLDeskProductionBehavior();
                    break;
                case "RightL":
                    this._productionBehavior = new RightLDeskProductionBehavior();
                    break;
                case "Standard":
                    this._productionBehavior = new StandardDeskProductionBehavior();
                    break;
                case "Rolltop":
                    this._productionBehavior = new RolltopDeskProductionBehavior();
                    break;
                case "Executive":
                    this._productionBehavior = new ExecutiveDeskProductionBehavior();
                    break;
            }
            
        }

        public Desk Build()
        {
            this.SetProductionBehavior(_buildQue.Model);
            return this.Finish(this._productionBehavior.Build(_buildQue.Material));
        }

        public Desk Finish(Desk assembledDesk)
        {
            Desk desk = null;
            switch (this._buildQue.Color)
            {
                case "Black":
                    desk = new BlackColor(assembledDesk);
                    break;
                case "White":
                    desk = new WhiteColor(assembledDesk);
                    break;
                case "Bronze":
                    desk = new BronzeColor(assembledDesk);
                    break;
                case "Gray":
                    desk = new GrayColor(assembledDesk);
                    break;
                case "Cherry":
                    desk = new CherryColor(assembledDesk);
                    break;
                case "Maple":
                    desk = new MapleColor(assembledDesk);
                    break;
                case "Walnut":
                    desk = new WalnutColor(assembledDesk);
                    break;
                default:
                    desk = assembledDesk;
                    break;
            }

            return desk;
        }

        #endregion

    }
}
